// run: $exec < input
#include <iostream>
#include <vector>
#include <tuple>

int const maxn = 110000;
int head[maxn], end_point[2 * maxn], next[2 * maxn];
int alloc = 1;
int n, m;

std::vector<std::tuple<int, int, int>> ans;

void add_edge(int x, int y)
{
	end_point[alloc] = y; next[alloc] = head[x]; head[x] = alloc++;
	end_point[alloc] = x; next[alloc] = head[y]; head[y] = alloc++;
}

void make_cut(int & last, int u, int v)
{
	if (last) {
		ans.push_back(std::make_tuple(last, u, v));
		last = 0;
	} else last = v;
}

int vis[maxn];

int dfs(int u)
{
	vis[u] = 1;
	int last = 0;
	for (int p = head[u]; p; p = next[p]) {
		int v = end_point[p];
		if (vis[v] == 1) continue;
		if (vis[v] == 2) { make_cut(last, u, v); continue; }
		int t = dfs(v);
		if (t) ans.push_back(std::make_tuple(t, v, u));
		else make_cut(last, u, v);
	}
	vis[u] = 2;
	return last;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> m;
	for (int i = 0, x, y; i < m; i++) {
		std::cin >> x >> y;
		add_edge(x, y);
	}

	if (dfs(1))
		std::cout << "No solution\n";
	else
		for (auto i : ans)
			std::cout << std::get<0>(i) << ' ' << std::get<1>(i) << ' '
				<< std::get<2>(i) << '\n';
}

